package com.changgou.util;

import com.google.gson.*;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 老大哥在看着你
 *
 * @author ANG.YU
 * @date 2019-09-22 11:05
 */
public class HighlightResultMapper implements SearchResultMapper {
    @Autowired
    private Gson gson = new GsonBuilder()
            //.setDateFormat("yyyy-MM-dd 'T' HH:mm:ss 'Z'")
            //.setDateFormat("yyyy-MM-dd HH:mm:ss")
            .registerTypeAdapter(Date.class,new DateDeserializer())
            .create();
    @Override
    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
        String scrollId = response.getScrollId();
        long total = response.getHits().getTotalHits();
        float maxScore = response.getHits().getMaxScore();

        List<T> list = new ArrayList<>();
        for (SearchHit hit : response.getHits()) {
            String source = hit.getSourceAsString();
            System.out.println("source = " + source);
            T t = gson.fromJson(source, clazz);
            // 处理高亮
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFields)) {
                for (Map.Entry<String, HighlightField> entry : highlightFields.entrySet()) {
                    String fieldName = entry.getKey();
                    String value = StringUtils.join(entry.getValue().getFragments());
                    try {
                        BeanUtils.setProperty(t, fieldName, value);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            list.add(t);
        }
        return new AggregatedPageImpl<>(list, pageable, total, response.getAggregations(), scrollId, maxScore);
    }

    private static class DateDeserializer implements JsonDeserializer<Date> {

        private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        @Override
        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            if (json != null) {
                final String jsonString = json.getAsString();
                try {
                    return dateFormat.parse(jsonString);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                final long jsonLong= json.getAsLong();
                try {
                    return new Date(jsonLong);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }
}
